package com.heima.aspect;

import com.heima.annotation.AutoFill;
import com.heima.annotation.OperationFill;
import com.heima.constant.BaseContextConstant;
import com.heima.context.BaseContext;
import com.heima.enumeration.OperationType;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.List;

@Aspect
@Component
public class AutoFillAspect {
    @Pointcut("execution(* com.heima.mapper.*.*(..)) && @annotation(com.heima.annotation.AutoFill)")
    public void pointCut() {
    }

    @Before("pointCut()")
    public void AutoFill(JoinPoint joinPoint) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        // 获取所对应的注解的值
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        OperationType value = signature.getMethod().getAnnotation(AutoFill.class).value();

        // 获取参数的类型
        Object[] args = joinPoint.getArgs();
        if (args == null || args.length == 0) {
            return;
        }

        Object arg = args[0];  // 固定一个参数

        if (OperationType.INSERT.equals(value)) {
            insert(arg);
        }

        if (OperationType.BATCH_INSERT.equals(value)) {
           List list = (List) arg;
            for (Object item :list){
                insert(item);
            }
        }

        if (OperationType.UPDATE.equals(value)) {
            update(arg);
        }

    }

    public void insert(Object arg) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Method setCreateTime = arg.getClass().getMethod("setCreateTime", LocalDateTime.class);
        Method setUpdateTime = arg.getClass().getMethod("setUpdateTime", LocalDateTime.class);
        Method setCreateBy = arg.getClass().getMethod("setCreateBy", String.class);
        Method setUpdateBy = arg.getClass().getMethod("setUpdateBy", String.class);


        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);
        setCreateTime.invoke(arg, now);
        setUpdateTime.invoke(arg, now);
        String userName = (String) BaseContext.getData(BaseContextConstant.USERNAME);
        setCreateBy.invoke(arg,userName);
        setUpdateBy.invoke(arg,userName);
    }

    public void update(Object arg) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Method setUpdateTime = arg.getClass().getMethod("setUpdateTime", LocalDateTime.class);
        Method setUpdateBy = arg.getClass().getMethod("setUpdateBy", String.class);

        LocalDateTime now = LocalDateTime.now();
        setUpdateTime.invoke(arg, now);
        String userName = (String) BaseContext.getData(BaseContextConstant.USERNAME);
        setUpdateBy.invoke(arg,userName);
    }
}
